/* syscalls.h
 * By: Spencer Clark
 * Date created: March 7th 2011
 * Date modified: April 7th 2011
 * Modified by: Spencer Clark
 */

#ifndef _XXXOS_SYSCALLS_H
#define _XXXOS_SYSCALLS_H

#include <proc.h>
#include <memory.h>
#include <stdarg.h>
#include <syscall_tags.h>

/*********************************/
/*** Syscall stuff ... ***********/
/*********************************/

/* System calls should pass their parameters on the stack; this tells GCC to
 * make sure they do */
#define scall __attribute__((regparm(0))) 

/* System calls that would otherwise return type 'void' should return type
 * srval, with the result being negative on error or >= 0 on success */
typedef short int srval;

/* Procedure syscall: performs a system call
 * sysc_tag, int, ... -> int
 * Triggers a software interrupt to call the system call identified by the
 * given tag. argc must hold an integer indicating the number of arguments
 * for the given function. After argc follow the arguments that should be
 * passed to the system call.
 * pre: ?
 * post: the arguments to the system call have been validated, and if they are
 *       valid the system call has been performed.
 * return: 0 on success
 *        -1 on error/invalid args
 */
int syscall(sysc_tag, int argc, ...);


/*********************************/
/*** Syscall Prototypes **********/
/*********************************/

/* Process-related system calls */
/*------------------------------*/

/* Procedure fork:
 * void -> pid_t
 * Creates a child process that differs from the parent process only in its PID
 * and PPID.
 * Pre: nil
 * Post: A new process is created with a new PID
 * Return: On success, the PID of the child process is returned in the parent's
 *         thread of execution, and a 0 is returned in the child's thread of
 *         execution. On failure, a -1 will be returned in the parent's context.
 * Note: Currently returns 0x42 simply as a test of returning a value
 */
scall pid_t fork(void);
int validate_fork(va_list);

/* Procedure spork:
 * Not sure what this will do yet, but it will be awesome.
 * Note: Currently takes in
 */
void spork(int);
int validate_spork(va_list);

/* Procedure yield:
 * void -> srval
 * Give up the remainder of the calling process's quantum and run the scheduler.
 * Pre: nil
 * Post: The running process has been stopped and the scheduler was called
 */
/* scall void sys_yield(void); */

/* Procedure exit:
 * Kill the calling process, freeing all of its resources. Not sure what to do
 * with children yet...?
 */
/* scall void sys_exit(srval* result); */


/* I/O system calls */
/*------------------*/

/* Procedure read:
 * fid, void*, unsigned long* -> srval
 * Read the number of bytes specified in len from file into the memory pointed
 * to by dest.
 * Pre: dest points to user-space memory with size len
 *      file is a valid file descriptor 
 * Post: len bytes (or all available bytes in file) have been copied to dest.
 *       len will be set to the number of bytes copied!
 * Returns: -1 on error
 *           0 on success
 */ 
/* scall void sys_read(srval* result, fid file, void* dest, unsigned long* len);*/

/* Procedure write:
 * fid, void*, unsigned long* -> srval
 * Write the number of bytes specified in len from src into file.
 * Pre: src points to user-space memory of size len
 *      file is a valid file descriptor
 * Post: min(len, size of file, size of memory at src) have been copied to file
 *       len will be set to the number of bytes copied!
 */
/* scall void sys_write(srval* result, fid file, void* src, unsigned long* len);*/

#endif /* _XXXOS_SYSCALLS_H */

